# -*- coding: utf-8 -*-
from part import *
from material import *
from section import *
from assembly import *
from step import *
from interaction import *
from load import *
from mesh import *
from optimization import *
from job import *
from sketch import *
from visualization import *
from connectorBehavior import *

import math

class GenerateAuxeticStructure():
    def __init__(self,H,D,theta,x_n, y_n, z_n):
        self.H = H
        self.D = D
        self.theta = theta
        self.x_n = x_n
        self.y_n = y_n
        self.z_n = z_n
    
    def part(self):

        H = self.H
        D = self.D
        theta = self.theta
        x_n = self.x_n
        y_n = self.y_n
        z_n = self.z_n

        # 最终所有线段集合
        lines = []

        # 生成x轴方向的折线
        def generateXLines():

            # x轴方向的折线的集合
            lines = []

            # x轴方向四条折线坐标集合
            line1 = []
            line2 = []
            line3 = []
            line4 = []

            # 沿y轴复制折线列表
            copy_4_lines = []

            # x轴方向四条折线奇数点坐标列表
            line1_odd_point_list = []
            line2_odd_point_list = []
            line3_odd_point_list = []
            line4_odd_point_list = []

            # x轴方向四条折线偶数点坐标列表
            line1_even_point_list = []
            line2_even_point_list = []
            line3_even_point_list = []
            line4_even_point_list = []

            # x方向上，奇数点坐标
            for i in range(x_n + 1):
                line1_odd_point = ( i * 2 * D, 0, 0)
                line1_odd_point_list.append(line1_odd_point)  

                line2_odd_point = ( i * 2 * D, 0, H)
                line2_odd_point_list.append(line2_odd_point)

                line3_odd_point = ( i * 2 * D, D, D / math.tan(theta))
                line3_odd_point_list.append(line3_odd_point)

                line4_odd_point = ( i * 2 * D, D, H - D / math.tan(theta))
                line4_odd_point_list.append(line4_odd_point)

            # x方向上，偶数点坐标
            for j in range(x_n):
                line1_even_point = ( (j + 1) * 2 * D - D, 0, D / math.tan(theta))
                line1_even_point_list.append(line1_even_point)  

                line2_even_point = ( (j + 1) * 2 * D - D, 0, H - D / math.tan(theta))
                line2_even_point_list.append(line2_even_point)

                line3_even_point = ( (j + 1) * 2 * D - D, D, 0)
                line3_even_point_list.append(line3_even_point)  

                line4_even_point = ( (j + 1) * 2 * D - D, D, H)
                line4_even_point_list.append(line4_even_point)


            # 将点坐标两两配对，形成线段两端坐标对
            for k in range(x_n):
                line1_points_1 = (line1_odd_point_list[k],line1_even_point_list[k])
                line1_points_2 = (line1_even_point_list[k],line1_odd_point_list[k+1])
                line1.append(line1_points_1)
                line1.append(line1_points_2)

                line2_points_1 = (line2_odd_point_list[k],line2_even_point_list[k])
                line2_points_2 = (line2_even_point_list[k],line2_odd_point_list[k+1])
                line2.append(line2_points_1)
                line2.append(line2_points_2)

                line3_points_1 = (line3_odd_point_list[k],line3_even_point_list[k])
                line3_points_2 = (line3_even_point_list[k],line3_odd_point_list[k+1])
                line3.append(line3_points_1)
                line3.append(line3_points_2)

                line4_points_1 = (line4_odd_point_list[k],line4_even_point_list[k])
                line4_points_2 = (line4_even_point_list[k],line4_odd_point_list[k+1])
                line4.append(line4_points_1)
                line4.append(line4_points_2)
            
            for l in range(y_n + 1):

                for each1 in line1:
                    newLine1 = ((each1[0][0],each1[0][1] + 2 * D * l,each1[0][2]),((each1[1][0],each1[1][1] + 2 * D * l,each1[1][2])))
                    copy_4_lines.append(newLine1)

                for each2 in line2:
                    newLine2 = ((each2[0][0],each2[0][1] + 2 * D * l,each2[0][2]),((each2[1][0],each2[1][1] + 2 * D * l,each2[1][2])))
                    copy_4_lines.append(newLine2)  

            for m in range(y_n):

                for each3 in line3:
                    newLine3 = ((each3[0][0],each3[0][1] + 2 * D * m,each3[0][2]),((each3[1][0],each3[1][1] + 2 * D * m,each3[1][2])))
                    copy_4_lines.append(newLine3)

                for each4 in line4:
                    newLine4 = ((each4[0][0],each4[0][1] + 2 * D * m,each4[0][2]),((each4[1][0],each4[1][1] + 2 * D * m,each4[1][2])))
                    copy_4_lines.append(newLine4) 

            lines = line1 + line2 + line3 + line4 + copy_4_lines

            return lines

        # 生成y轴方向的折线
        def generateYLines():

            # y轴方向的折线的集合
            lines = []

            # y轴方向四条折线坐标集合
            line1 = []
            line2 = []
            line3 = []
            line4 = []

            # 沿x轴复制折线列表
            copy_4_lines = []

            # y轴方向四条折线奇数点坐标列表
            line1_odd_point_list = []
            line2_odd_point_list = []
            line3_odd_point_list = []
            line4_odd_point_list = []

            # y轴方向四条折线偶数点坐标列表
            line1_even_point_list = []
            line2_even_point_list = []
            line3_even_point_list = []
            line4_even_point_list = []

            # y方向上，奇数点坐标
            for i in range(y_n + 1):
                line1_odd_point = ( 0, i * 2 * D, 0)
                line1_odd_point_list.append(line1_odd_point)  

                line2_odd_point = ( 0, i * 2 * D, H)
                line2_odd_point_list.append(line2_odd_point)

                line3_odd_point = ( D, i * 2 * D, D / math.tan(theta))
                line3_odd_point_list.append(line3_odd_point)

                line4_odd_point = ( D, i * 2 * D, H - D / math.tan(theta))
                line4_odd_point_list.append(line4_odd_point)

            # y方向上，偶数点坐标
            for j in range(y_n):
                line1_even_point = ( 0, (j + 1) * 2 * D - D, D / math.tan(theta))
                line1_even_point_list.append(line1_even_point)  

                line2_even_point = ( 0, (j + 1) * 2 * D - D, H - D / math.tan(theta))
                line2_even_point_list.append(line2_even_point)

                line3_even_point = ( D, (j + 1) * 2 * D - D, 0)
                line3_even_point_list.append(line3_even_point)  

                line4_even_point = ( D, (j + 1) * 2 * D - D, H)
                line4_even_point_list.append(line4_even_point)


            # 将点坐标两两配对，形成线段两端坐标对
            for k in range(y_n):
                line1_points_1 = (line1_odd_point_list[k],line1_even_point_list[k])
                line1_points_2 = (line1_even_point_list[k],line1_odd_point_list[k+1])
                line1.append(line1_points_1)
                line1.append(line1_points_2)

                line2_points_1 = (line2_odd_point_list[k],line2_even_point_list[k])
                line2_points_2 = (line2_even_point_list[k],line2_odd_point_list[k+1])
                line2.append(line2_points_1)
                line2.append(line2_points_2)

                line3_points_1 = (line3_odd_point_list[k],line3_even_point_list[k])
                line3_points_2 = (line3_even_point_list[k],line3_odd_point_list[k+1])
                line3.append(line3_points_1)
                line3.append(line3_points_2)

                line4_points_1 = (line4_odd_point_list[k],line4_even_point_list[k])
                line4_points_2 = (line4_even_point_list[k],line4_odd_point_list[k+1])
                line4.append(line4_points_1)
                line4.append(line4_points_2)

            # 沿x轴复制折线
            
            for l in range(x_n + 1):

                for each1 in line1:
                    newLine1 = ((each1[0][0] + 2 * D * l,each1[0][1],each1[0][2]),((each1[1][0] + 2 * D * l,each1[1][1],each1[1][2])))
                    copy_4_lines.append(newLine1)

                for each2 in line2:
                    newLine2 = ((each2[0][0] + 2 * D * l,each2[0][1],each2[0][2]),((each2[1][0] + 2 * D * l,each2[1][1],each2[1][2])))
                    copy_4_lines.append(newLine2)  

            for m in range(x_n):

                for each3 in line3:
                    newLine3 = ((each3[0][0] + 2 * D * m,each3[0][1],each3[0][2]),((each3[1][0] + 2 * D * m,each3[1][1],each3[1][2])))
                    copy_4_lines.append(newLine3)

                for each4 in line4:
                    newLine4 = ((each4[0][0] + 2 * D * m,each4[0][1],each4[0][2]),((each4[1][0] + 2 * D * m,each4[1][1],each4[1][2])))
                    copy_4_lines.append(newLine4) 

            lines = line1 + line2 + line3 + line4 + copy_4_lines

            return lines

        # 层内部的垂直线段
        def generateVerticalLines():

            line_list = []
            line_odd_list = []
            line_even_list = []

            for i in range(x_n + 1):
                line_odd_down_point = (i * 2 * D, 0, 0)
                line_odd_up_point = (i * 2 * D, 0, H)
                line_odd = (line_odd_down_point, line_odd_up_point)
                line_odd_list.append(line_odd)

            for j in range(x_n):
                line_even_down_point = (j * 2 * D + D, D, 0)
                line_even_up_point = (j * 2 * D + D, D, H)
                line_even = (line_even_down_point, line_even_up_point)
                line_even_list.append(line_even)
            
            line_list = line_odd_list + line_even_list

            for m in range(y_n):
                for each_odd in line_odd_list:
                    new_line_odd_down_point = (each_odd[0][0], each_odd[0][1] + (m + 1) * 2 * D, each_odd[0][2])
                    new_line_odd_up_point = (each_odd[1][0], each_odd[1][1] + (m + 1) * 2 * D, each_odd[1][2])
                    new_line_odd = (new_line_odd_down_point, new_line_odd_up_point)

                    line_list.append(new_line_odd)
            
            for n in range(y_n - 1):
                for each_even in line_even_list:
                    new_line_even_down_point = (each_even[0][0], each_even[0][1] + (n + 1) * 2 * D, each_even[0][2])
                    new_line_even_up_point = (each_even[1][0], each_even[1][1] + (n + 1) * 2 * D, each_even[1][2])
                    new_line_even = (new_line_even_down_point, new_line_even_up_point)

                    line_list.append(new_line_even)
            
            return line_list

        # 将绘制好的单层在z轴方向进行复制
        def copyLayer(need_copy_layer):
            copy_layer = []
            move_distance = H + H - 2 * D / math.tan(theta)
            for i in range(z_n - 1):
                for each_line in need_copy_layer:
                    copy_line_point_1 = (each_line[0][0],each_line[0][1],each_line[0][2] + (i + 1) * move_distance)
                    copy_line_point_2 = (each_line[1][0],each_line[1][1],each_line[1][2] + (i + 1) * move_distance)
                    copy_line = (copy_line_point_1,copy_line_point_2)
                    copy_layer.append(copy_line)
            
            return copy_layer

        def generateLayerLinks():

            layer_link_list = []
            layer_link_odd_list = []
            layer_link_even_list = []

            # 多层之间才有连杆
            if(z_n > 1):    

                for i in range(x_n + 1):

                    layer_link_odd_down_point = (i * 2 * D, D, H - D / math.tan(theta))
                    layer_link_odd_up_point = (i * 2 * D, D, H + H - D / math.tan(theta))
                    layer_link_odd = (layer_link_odd_down_point, layer_link_odd_up_point)
                    layer_link_odd_list.append(layer_link_odd)

                for j in range(x_n):

                    layer_link_even_down_point = (j * 2 * D + D, 0, H - D / math.tan(theta))
                    layer_link_even_up_point = (j * 2 * D + D, 0, H + H - D / math.tan(theta))
                    layer_link_even = (layer_link_even_down_point, layer_link_even_up_point)
                    layer_link_even_list.append(layer_link_even)
                
                layer_link_list = layer_link_odd_list + layer_link_even_list

                for m in range(y_n - 1):
                    for each_odd in layer_link_odd_list:
                        new_line_odd_down_point = (each_odd[0][0], each_odd[0][1] + (m + 1) * 2 * D, each_odd[0][2])
                        new_line_odd_up_point = (each_odd[1][0], each_odd[1][1] + (m + 1) * 2 * D, each_odd[1][2])
                        new_line_odd = (new_line_odd_down_point, new_line_odd_up_point)

                        layer_link_list.append(new_line_odd)
                
                for n in range(y_n):
                    for each_even in layer_link_even_list:
                        new_line_even_down_point = (each_even[0][0], each_even[0][1] + (n + 1) * 2 * D, each_even[0][2])
                        new_line_even_up_point = (each_even[1][0], each_even[1][1] + (n + 1) * 2 * D, each_even[1][2])
                        new_line_even = (new_line_even_down_point, new_line_even_up_point)

                        layer_link_list.append(new_line_even)

            return layer_link_list

        def copyLayerLinks(need_copy_layer_links):

            layer_links = []

            move_distance = H + H - 2 * D / math.tan(theta)
            for i in range(z_n - 2):
                for each_line in need_copy_layer_links:
                    copy_line_point_1 = (each_line[0][0],each_line[0][1],each_line[0][2] + (i + 1) * move_distance)
                    copy_line_point_2 = (each_line[1][0],each_line[1][1],each_line[1][2] + (i + 1) * move_distance)
                    copy_line = (copy_line_point_1,copy_line_point_2)
                    layer_links.append(copy_line)
            
            return layer_links

        # 生成底部竖直线
        def generateBottomLines():

            bottom_line_list = []
            bottom_line_odd_list = []
            bottom_line_even_list = []

            for i in range(x_n + 1):

                bottom_line_odd_down_point = (i * 2 * D, D, D / math.tan(theta) - 0.5 * H)
                bottom_line_odd_up_point = (i * 2 * D, D, D / math.tan(theta))
                bottom_line_odd = (bottom_line_odd_down_point, bottom_line_odd_up_point)
                bottom_line_odd_list.append(bottom_line_odd)

            for j in range(x_n):

                bottom_line_even_down_point = (j * 2 * D + D, 0, D / math.tan(theta) - 0.5 * H)
                bottom_line_even_up_point = (j * 2 * D + D, 0, D / math.tan(theta))
                bottom_line_even = (bottom_line_even_down_point, bottom_line_even_up_point)
                bottom_line_even_list.append(bottom_line_even)
                
            bottom_line_list = bottom_line_odd_list + bottom_line_even_list

            for m in range(y_n - 1):
                for each_odd in bottom_line_odd_list:
                    new_line_odd_down_point = (each_odd[0][0], each_odd[0][1] + (m + 1) * 2 * D, each_odd[0][2])
                    new_line_odd_up_point = (each_odd[1][0], each_odd[1][1] + (m + 1) * 2 * D, each_odd[1][2])
                    new_line_odd = (new_line_odd_down_point, new_line_odd_up_point)

                    bottom_line_list.append(new_line_odd)
                
            for n in range(y_n):
                for each_even in bottom_line_even_list:
                    new_line_even_down_point = (each_even[0][0], each_even[0][1] + (n + 1) * 2 * D, each_even[0][2])
                    new_line_even_up_point = (each_even[1][0], each_even[1][1] + (n + 1) * 2 * D, each_even[1][2])
                    new_line_even = (new_line_even_down_point, new_line_even_up_point)

                    bottom_line_list.append(new_line_even)
            
            return bottom_line_list

        # 生成顶部竖直线
        def generateTopLines():

            top_line_list = []
            top_line_odd_list = []
            top_line_even_list = []

            for i in range(x_n + 1):

                top_line_odd_down_point = (i * 2 * D, D, H - D / math.tan(theta) + (z_n - 1) * (H + H - 2 * D / math.tan(theta)))
                top_line_odd_up_point = (i * 2 * D, D, H - D / math.tan(theta) + (z_n - 1) * (H + H - 2 * D / math.tan(theta)) + 0.5 * H)
                top_line_odd = (top_line_odd_down_point, top_line_odd_up_point)
                top_line_odd_list.append(top_line_odd)

            for j in range(x_n):

                top_line_even_down_point = (j * 2 * D + D, 0, H - D / math.tan(theta) + (z_n - 1) * (H + H - 2 * D / math.tan(theta)))
                top_line_even_up_point = (j * 2 * D + D, 0, H - D / math.tan(theta) + (z_n - 1) * (H + H - 2 * D / math.tan(theta)) + 0.5 * H)
                top_line_even = (top_line_even_down_point, top_line_even_up_point)
                top_line_even_list.append(top_line_even)
                
            top_line_list = top_line_odd_list + top_line_even_list

            for m in range(y_n - 1):
                for each_odd in top_line_odd_list:
                    new_line_odd_down_point = (each_odd[0][0], each_odd[0][1] + (m + 1) * 2 * D, each_odd[0][2])
                    new_line_odd_up_point = (each_odd[1][0], each_odd[1][1] + (m + 1) * 2 * D, each_odd[1][2])
                    new_line_odd = (new_line_odd_down_point, new_line_odd_up_point)

                    top_line_list.append(new_line_odd)
                
            for n in range(y_n):
                for each_even in top_line_even_list:
                    new_line_even_down_point = (each_even[0][0], each_even[0][1] + (n + 1) * 2 * D, each_even[0][2])
                    new_line_even_up_point = (each_even[1][0], each_even[1][1] + (n + 1) * 2 * D, each_even[1][2])
                    new_line_even = (new_line_even_down_point, new_line_even_up_point)

                    top_line_list.append(new_line_even)
            
            return top_line_list

        # 生成x轴方向的折线
        x_lines = generateXLines()

        # 生成y轴方向的折线
        y_lines = generateYLines()

        # 生成单层内部的竖直线段
        vertical_lines = generateVerticalLines()

        # x,y和竖直方向的所有线段相加，得到单层结构
        layer_lines = x_lines + y_lines + vertical_lines

        # 将单层在z轴方向进行复制
        copy_layer = copyLayer(layer_lines)

        # 生成层与层之间的连杆
        layer_links = generateLayerLinks()

        # 将层与层之间的连杆在z轴方向进行复制
        copy_layer_links = copyLayerLinks(layer_links)

        # 生成顶部和底部的竖线
        bottom_lines = generateBottomLines()
        top_lines = generateTopLines()

        # 将各个部分线段汇总
        lines = layer_lines + copy_layer + layer_links + copy_layer_links + bottom_lines + top_lines

        lines_tuple = tuple(lines)

        mdb.models['Model-1'].Part(dimensionality=THREE_D, name='Part-1', type=DEFORMABLE_BODY)

        mdb.models['Model-1'].parts['Part-1'].WirePolyLine(mergeType=IMPRINT, meshable=ON, points=lines_tuple)

        mdb.models['Model-1'].parts['Part-1'].Set(edges=mdb.models['Model-1'].parts['Part-1'].edges.getSequenceFromMask(('[#3 ]', ), ), name='Wire-2-Set-1')

def main(H,D,theta,x_n, y_n, z_n):
    print('generate start')
    generateAuxeticStructure = GenerateAuxeticStructure(H,D,theta,x_n, y_n, z_n)
    generateAuxeticStructure.part()
    print('generate end')

if __name__ == '__main__':

    main(H=3.0,D=1.05,theta=45.0,x_n=3,y_n=3,z_n=3)

